home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
pcl_src.zoo
/
braid.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1992-08-12
|
35KB
|
847 lines
;;;-*-Mode:LISP; Package:(PCL (LISP WALKER)); Base:10; Syntax:Common-lisp -*-
;;;
;;; *************************************************************************
;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
;;; All rights reserved.
;;;
;;; Use and copying of this software and preparation of derivative works
;;; based upon this software are permitted. Any distribution of this
;;; software or derivative works must comply with all applicable United
;;; States export control laws.
;;;
;;; This software is made available AS IS, and Xerox Corporation makes no
;;; warranty about the software, its performance or its conformity to any
;;; specification.
;;;
;;; Any person obtaining a copy of this software is requested to send their
;;; name and post office or electronic mail address to:
;;; CommonLoops Coordinator
;;; Xerox PARC
;;; 3333 Coyote Hill Rd.
;;; Palo Alto, CA 94304
;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
;;;
;;; Suggestions, comments and requests for improvements are also welcome.
;;; *************************************************************************
;;;
;;; Bootstrapping the meta-braid.
;;;
;;; The code in this file takes the early definitions that have been saved
;;; up and actually builds those class objects. This work is largely driven
;;; off of those class definitions, but the fact that STANDARD-CLASS is the
;;; class of all metaclasses in the braid is built into this code pretty
;;; deeply.
;;;
;;;
(in-package 'pcl)
(defun early-class-name (class)
(bootstrap-get-slot 'class class 'name))
(defun early-class-definition (class-name)
(or (find class-name *early-class-definitions* :key #'ecd-class-name)
(error "~S is not a class in *early-class-definitions*." class-name)))
(defun canonical-slot-name (canonical-slot)
(getf canonical-slot :name))
(defun early-collect-inheritance (class-name)
(declare (values slots cpl default-initargs direct-subclasses))
(let ((cpl (early-collect-cpl class-name)))
(values (early-collect-slots cpl)
cpl
(early-collect-default-initargs cpl)
(gathering1 (collecting)
(dolist (definition *early-class-definitions*)
(when (memq class-name (ecd-superclass-names definition))
(gather1 (ecd-class-name definition))))))))
(defun early-collect-cpl (class-name)
(labels ((walk (c)
(let* ((definition (early-class-definition c))
(supers (ecd-superclass-names definition)))
(cons c
(apply #'append (mapcar #'early-collect-cpl supers))))))
(remove-duplicates (walk class-name) :from-end nil :test #'eq)))
(defun early-collect-slots (cpl)
(let* ((definitions (mapcar #'early-class-definition cpl))
(super-slots (mapcar #'ecd-canonical-slots definitions))
(slots (apply #'append (reverse super-slots))))
(dolist (s1 slots)
(let ((name1 (canonical-slot-name s1)))
(dolist (s2 (cdr (memq s1 slots)))
(when (eq name1 (canonical-slot-name s2))
(error "More than one early class defines a slot with the~%~
name ~S. This can't work because the bootstrap~%~
object system doesn't know how to compute effective~%~
slots."
name1)))))
slots))
(defun early-collect-default-initargs (cpl)
(let ((default-initargs ()))
(dolist (class-name cpl)
(let ((definition (early-class-definition class-name)))
(dolist (option (ecd-other-initargs definition))
(unless (eq (car option) :default-initargs)
(error "The defclass option ~S is not supported by the bootstrap~%~
object system."
(car option)))
(setq default-initargs
(nconc default-initargs (reverse (cdr option)))))))
(reverse default-initargs)))
;;;
;;; bootstrap-get-slot and bootstrap-set-slot are used to access and change
;;; the values of slots during bootstrapping. During bootstrapping, there
;;; are only two kinds of objects whose slots we need to access, CLASSes
;;; and SLOT-DEFINITIONs. The first argument to these functions tells whether the
;;; object is a CLASS or a SLOT-DEFINITION.
;;;
;;; Note that the way this works it stores the slot in the same place in
;;; memory that the full object system will expect to find it later. This
;;; is critical to the bootstrapping process, the whole changeover to the
;;; full object system is predicated on this.
;;;
;;; One important point is that the layout of standard classes and standard
;;; slots must be computed the same way in this file as it is by the full
;;; object system later.
;;;
(defun bootstrap-get-slot (type object slot-name)
(let ((index (bootstrap-slot-index type slot-name)))
(svref (std-instance-slots object) index)))
(defun bootstrap-set-slot (type object slot-name new-value)
(let ((index (bootstrap-slot-index type slot-name)))
(setf (svref (std-instance-slots object) index) new-value)))
(defvar *early-class-slots* nil)
(defun early-class-slots (class-name)
(cdr (or (assoc class-name *early-class-slots*)
(let ((a (cons class-name
(mapcar #'canonical-slot-name
(early-collect-inheritance class-name)))))
(push a *early-class-slots*)
a))))
(defun early-class-original-static-slot-storage-copy (class-name)
(%allocate-origional-static-slot-storage-copy
(length (the list (early-class-slots class-name)))))
(defun bootstrap-slot-index (class-name slot-name)
(or (posq slot-name (the list (early-class-slots class-name)))
(error "~S not found" slot-name)))
;;;
;;; bootstrap-meta-braid
;;;
;;; This function builds the base metabraid from the early class definitions.
;;;
(defun bootstrap-meta-braid ()
(let* ((slot-class-original-slot-copy
(early-class-original-static-slot-storage-copy 'slot-class))
(standard-class-original-slot-copy
(early-class-original-static-slot-storage-copy 'standard-class))
(built-in-class-original-slot-copy
(early-class-original-static-slot-storage-copy 'built-in-class))
(structure-class-original-slot-copy
(early-class-original-static-slot-storage-copy 'structure-class))
(slot-class (%allocate-instance--class standard-class-original-slot-copy))
(standard-class (%allocate-instance--class standard-class-original-slot-copy))
(built-in-class (%allocate-instance--class standard-class-original-slot-copy))
(structure-class (%allocate-instance--class standard-class-original-slot-copy))
(direct-slotd (%allocate-instance--class standard-class-original-slot-copy))
(effective-slotd (%allocate-instance--class standard-class-original-slot-copy))
(class-eq (%allocate-instance--class standard-class-original-slot-copy))
(slot-class-wrapper (make-wrapper slot-class))
(standard-class-wrapper (make-wrapper standard-class))
(built-in-class-wrapper (make-wrapper built-in-class))
(structure-class-wrapper (make-wrapper structure-class))
(direct-slotd-wrapper (make-wrapper direct-slotd))
(effective-slotd-wrapper (make-wrapper effective-slotd))
(class-eq-wrapper (make-wrapper class-eq)))
;;
;; First, make a class metaobject for each of the early classes. For
;; each metaobject we also set its wrapper. Except for the class T,
;; the wrapper is always that of STANDARD-CLASS.
;;
(dolist (definition *early-class-definitions*)
(let* ((name (ecd-class-name definition))
(meta (ecd-metaclass definition))
(original-slot-copy
(ecase meta
(slot-class slot-class-original-slot-copy)
(standard-class standard-class-original-slot-copy)
(built-in-class built-in-class-original-slot-copy)
(structure-class structure-class-original-slot-copy)))
(class (case name
(slot-class slot-class)
(standard-class standard-class)
(standard-direct-slot-definition direct-slotd)
(standard-effective-slot-definit